package cn.csc.module.order.dal.mysql.order;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.mapper.BaseMapperX;
import cn.csc.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csc.module.order.api.order.dto.OrderSimpleAmountInfoRespDTO;
import cn.csc.module.order.api.order.dto.OrderStatusRespDTO;
import cn.csc.module.order.controller.admin.order.vo.OrderPageReqVO;
import cn.csc.module.order.controller.admin.order.vo.OrderReqVO;
import cn.csc.module.order.controller.admin.order.vo.OrderWithItemAndAddrRespVO;
import cn.csc.module.order.controller.admin.order.vo.OrderWithItemRespVO;
import cn.csc.module.order.dal.dataobject.order.OrderDO;
import cn.csc.module.order.enums.OrderStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单信息 Mapper
 *
 * @author liuchuang
 */
@Mapper
public interface OrderMapper extends BaseMapperX<OrderDO> {

    default PageResult<OrderDO> selectAdminPage(OrderPageReqVO reqVO) {
        return selectPage(reqVO,new LambdaQueryWrapperX<OrderDO>()
                .eqIfPresent(OrderDO::getId, reqVO.getId())
                .eqIfPresent(OrderDO::getShopId, reqVO.getShopId())
                .likeIfPresent(OrderDO::getShopName, reqVO.getShopName())
                .likeIfPresent(OrderDO::getSpuName, reqVO.getSpuName())
                .eqIfPresent(OrderDO::getMemberPhone, reqVO.getMemberPhone())
                .neIfPresent(OrderDO::getOrderStatus, "0")
                .betweenIfPresent(OrderDO::getPayTime, reqVO.getPayTime())
                .orderByDesc(OrderDO::getPayTime));
    }
    default PageResult<OrderDO> selectPage(OrderPageReqVO reqVO) {
        return selectPage(reqVO,new LambdaQueryWrapperX<OrderDO>()
                .eqIfPresent(OrderDO::getUserId, reqVO.getUserId())
                .eqIfPresent(OrderDO::getShopId, reqVO.getShopId())
                .likeIfPresent(OrderDO::getShopName, reqVO.getShopName())
                .likeIfPresent(OrderDO::getSpuName, reqVO.getSpuName())
                .neIfPresent(OrderDO::getOrderStatus, "0")
                .apply(" ( CASE when "+reqVO.getOrderStatus()+"=4 then order_status <4  ELSE  order_status ="+reqVO.getOrderStatus()+" end )")
                .orderByDesc(OrderDO::getPayTime));
    }

    default List<OrderDO> selectExportList(OrderPageReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<OrderDO>()
                .eqIfPresent(OrderDO::getId, reqVO.getId())
                .eqIfPresent(OrderDO::getShopId, reqVO.getShopId())
                .likeIfPresent(OrderDO::getShopName, reqVO.getShopName())
                .likeIfPresent(OrderDO::getSpuName, reqVO.getSpuName())
                .eqIfPresent(OrderDO::getMemberPhone, reqVO.getMemberPhone())
                .neIfPresent(OrderDO::getOrderStatus, "0")
                .betweenIfPresent(OrderDO::getPayTime, reqVO.getPayTime())
                .orderByDesc(OrderDO::getPayTime));
    }

    default List<OrderDO> selectList(OrderReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<OrderDO>()
                .eqIfPresent(OrderDO::getOrderStatus, reqVO.getOrderStatus())
                .eqIfPresent(OrderDO::getDeliveryTime, reqVO.getDeliveryTime()));
    }
    /**
     * 获得订单状态下的数量信息
     *
     * @param orderStatus 订单状态
     * @return 订单信息
     */
    default Long getCountByStatus(int orderStatus, BigInteger shopId){
        return selectCount(new LambdaQueryWrapperX<OrderDO>()
                .neIfPresent(OrderDO::getOrderStatus, "0")
                .eqIfPresent(OrderDO::getShopId,shopId)
                .apply(" ( CASE when "+orderStatus+"=4 then order_status <4  ELSE  order_status ="+orderStatus+" end )"));
    }

    /**
     * 通过店铺ID列表获取店铺的订单数
     * @param list 店铺ID列表
     * @return
     */
    default List<Map<String, Object>> selectCountByShopIds(List<BigInteger> list){
        return selectMaps(new QueryWrapper<OrderDO>()
                .select("order.shop_id as shopId, count(*) as count")
                .ne("order_status", "0")
                .in("shop_id", list)
                .groupBy("shop_id")
        );
    }

    /**
     * 查询订单状态
     *
     * @param orderIds 多个订单的订单id
     * @return 订单状态列表
     */
    List<OrderStatusRespDTO> getOrdersStatus(List<BigInteger> orderIds);

    /**
     * 分页查询订单信息，包含订单子项
     * @param reqVO 查询参数
     * @return
     */
    Page<OrderWithItemRespVO> selectOrderWithItemsPage(@Param("req") OrderPageReqVO reqVO, IPage<OrderWithItemRespVO> page);

    /**
     * 分页查询订单信息，包含订单子项和地址
     * @param reqVO 查询参数
     * @return
     */
    Page<OrderWithItemAndAddrRespVO> selectWithItemsAndAddrsPage(@Param("req") OrderPageReqVO reqVO, IPage<OrderWithItemAndAddrRespVO> page);

    /**
     * 分页查询订单ID，包含订单子项和地址
     * @param reqVO
     * @param page
     * @return
     */
    Page<BigInteger> selectIdsWithItemsAndAddrsPage(@Param("req") OrderPageReqVO reqVO, IPage<BigInteger> page);


    List<OrderWithItemAndAddrRespVO> selectWithItemsAndAddrsList(@Param("req") OrderPageReqVO reqVO);


    List<OrderWithItemAndAddrRespVO> selectWithItemAndAddrPage(OrderPageReqVO reqVO);



    /**
     * 查询订单信息，包含订单子项
     * @param merchantOrderId 商户订单ID
     * @return
     */
    OrderWithItemRespVO selectOrderWithItems(String merchantOrderId);

    /**
     * 通过商户订单ID查询订单信息
     * @param merchantOrderId 商户订单ID
     * @return
     */
    default OrderDO selectByMerchantOrderId(String merchantOrderId){
        return selectOne(new LambdaQueryWrapperX<OrderDO>()
                .in(OrderDO::getMerchantOrderId, merchantOrderId));
    }

    default List<OrderDO> selectByOutTradeNos(List<BigInteger> outTradeNos){
        return selectList(new LambdaQueryWrapperX<OrderDO>()
                .in(OrderDO::getOutTradeNo, outTradeNos));
    }

    default Integer updateOrderNo(OrderDO orderDO){
        return update(null,new LambdaUpdateWrapper<OrderDO>()
                .set(OrderDO::getMerchantOrderId, orderDO.getMerchantOrderId())
                .set(OrderDO::getOutTradeNo, orderDO.getOutTradeNo())
                .set(OrderDO::getUpdateTime, LocalDateTime.now())
                .eq(OrderDO::getId, orderDO.getId()));
    }


    default Integer updateOrderStatusByOrderIds(List<BigInteger> orderIds){
        return update(null, new LambdaUpdateWrapper<OrderDO>()
                .set(OrderDO::getOrderStatus, OrderStatusEnum.SUCCESS.value())
                .set(OrderDO::getFinallyTime, LocalDateTime.now())
                .in(OrderDO::getId, orderIds));
    }



    /**
     * 将订单改为已支付状态
     *
     * @param merchantOrderId 订单ids
     */
    default Integer updateByToPaySuccess(String merchantOrderId){
        return update(null,new LambdaUpdateWrapper<OrderDO>()
                .set(OrderDO::getOrderStatus, OrderStatusEnum.PAYED.value())
                .set(OrderDO::getIsPayed, 1)
                .set(OrderDO::getPayTime, LocalDateTime.now())
                .set(OrderDO::getUpdateTime, LocalDateTime.now())
                .in(OrderDO::getMerchantOrderId, merchantOrderId));
    }

    /**
     * 根据订单id列表获取订单金额信息
     *
     * @param orderIds 订单id列表
     * @return
     */
    List<OrderSimpleAmountInfoRespDTO> getOrdersSimpleAmountInfo(List<BigInteger> orderIds);

    /**
     * 取消订单
     *
     * @param orderIds 订单ids
     */
    default Integer cancelOrders(List<BigInteger> orderIds){
        return update(null,new LambdaUpdateWrapper<OrderDO>()
                .set(OrderDO::getOrderStatus, 6)
                .set(OrderDO::getIsPayed, 0)
                .set(OrderDO::getPayTime, LocalDateTime.now())
                .set(OrderDO::getUpdateTime, LocalDateTime.now())
                .in(OrderDO::getId, orderIds));
    }

    default Integer updateOrderState(List<BigInteger> orderIds, Integer orderStatus){
        return update(null, new LambdaUpdateWrapper<OrderDO>()
                .set(OrderDO::getOrderStatus, orderStatus)
                .in(OrderDO::getId, orderIds));
    }
    default PageResult<OrderDO> selectPageV2(OrderPageReqVO reqVO) {
        return selectPage(reqVO,new LambdaQueryWrapperX<OrderDO>()
                .eqIfPresent(OrderDO::getUserId, reqVO.getUserId())
                .neIfPresent(OrderDO::getOrderStatus, "0")
                .apply(" ( CASE when "+reqVO.getOrderStatus()+"=4 then order_status <4  ELSE  order_status ="+reqVO.getOrderStatus()+" end )")
                .orderByDesc(OrderDO::getPayTime));
    }
    /**
     * 将订单改为已支付状态
     *
     * @param outTradeNos 订单ids
     */
    default List<OrderDO> selectToPaySuccess(List<BigInteger> outTradeNos){
        return selectList( new LambdaQueryWrapperX<OrderDO>()
                 .in(OrderDO::getOutTradeNo, outTradeNos));
    }

    /**
     * 查询订单id列表
     * @param outTradeNos 支付订单号
     * @return
     */
    default List<OrderDO> selectIds(List<BigInteger> outTradeNos){
        return selectList(new LambdaQueryWrapperX<OrderDO>()
                // 查询指定字段
                .select(OrderDO::getId)
                .in(OrderDO::getOutTradeNo, outTradeNos)
        );
    }

}
